let currentTabId;

chrome.tabs.onActivated.addListener(function (info) {
    updateSelectedUrl(info.tabId);
});

chrome.tabs.onUpdated.addListener(function (tabId, change, tab) {
    updateSelectedUrl(tabId);
});

chrome.bookmarks.onCreated.addListener(function (id, bookmark) {
    updateBookmarks();
});

chrome.bookmarks.onChanged.addListener(function (id, bookmark) {
    updateBookmarks();
});

chrome.bookmarks.onRemoved.addListener(function (id, bookmark) {
    updateBookmarks();
});

function isExisted(nodes, url) {
    return nodes.some(node => {
        if (node.children) {
            // 书签文件夹
            return isExisted(node.children, url);
        } else {
            // 书签
            return url == node.url;
        }
    });
}

let bookmarkTreeNodes;
async function updateBookmarks() {
    bookmarkTreeNodes = await chrome.bookmarks.getTree();
    chrome.tabs.query({
    }, function (tabs) {
        tabs && tabs.forEach(tab => updateSelectedUrl(tab.id));
    });
};

updateBookmarks();

async function updateSelectedUrl(tabId) {
    let existed = false;
    let tabInfo = await chrome.tabs.get(tabId);
    if (tabInfo?.url && bookmarkTreeNodes) {
        existed = isExisted(bookmarkTreeNodes, tabInfo.url);
    };
    await chrome.action.setIcon({
        path: existed ? "/assets/icon@2.png" : "/assets/icon.png",
        tabId: tabId,
    });
}


//////////// commands

chrome.commands.onCommand.addListener(async (command) => {
    console.log(`Command: ${command}`);
    switch (command) {
        case "AddBookmark": {
            addBookmark();
            break;
        }
    }
});

var StorageKey = {
    "BOOKMAP_MAPPINGS": "BOOKMAP_MAPPINGS3",
    "PREVIOUS_FOLDER": "PREVIOUS_FOLDER",
    "MUTEXT_RULES": "MUTEXT_RULES",
    "MUTEX_SAME_INDEX": "MUTEX_SAME_INDEX",
    "AUTO_CLOSE_POPUP": "AUTO_CLOSE_POPUP",
};
var StorageKeys = Object.values(StorageKey);
var DefaultBookmarkMappings = JSON.stringify([
]);
var DefaultMutextRules = JSON.stringify([
]);

let id2node = {};
let folder_path_separtor = " / ";

function recursiveBookmarkTreeNodes(nodes, parent, output) {
    // 重置
    if (!parent) {
        id2node = {};
    }
    if (!output) {
        output = [];
    }
    nodes.forEach(node => {
        id2node[node.id] = node;
        if (node.children) {
            // 书签文件夹
            if (node.id != 0) {
                output.push(node.id);
            }
            recursiveBookmarkTreeNodes(node.children, node, output);
        } else {
            // 书签
        }
    });
    return output;
}
function findBookmarkByUrl(nodes, url) {
    let ret = null;
    for (let node of nodes) {
        if (ret) break;
        if (node.children) {
            ret = findBookmarkByUrl(node.children, url);
        } else {
            // 书签
            if (node.url == url) {
                ret = node;
            }
        }
    }
    return ret;
}

async function addBookmark() {
    let bookmark_info;
    let result = await chrome.storage.sync.get(StorageKeys);
    let mappings = JSON.parse(result[StorageKey.BOOKMAP_MAPPINGS] || DefaultBookmarkMappings);
    let previsousFolder = result[StorageKey.PREVIOUS_FOLDER];
    let mutexRules = JSON.parse(result[StorageKey.MUTEXT_RULES] || DefaultMutextRules);
    let mutextSameIndex = result[StorageKey.MUTEX_SAME_INDEX] == 1;
    let tabs = await chrome.tabs.query({
        active: true,
        currentWindow: true
    });
    let tab = tabs[0];
    var tabId = tab.id;
    var tabUrl = tab.url;
    let preferedFolder;
    for (let mapping of mappings) {
        if (new RegExp(mapping[0]).test(tab.url)) {
            preferedFolder = mapping[1];
            break;
        }
    }
    let selectedFolder;
    let bookmarkTreeNodes = await chrome.bookmarks.getTree();
    bookmark_info = findBookmarkByUrl(bookmarkTreeNodes, tab.url);
    let folderIds = recursiveBookmarkTreeNodes(bookmarkTreeNodes);
    let parentId;
    let titles = folderIds.map((nodeid, i) => {
        let node;
        let titles = [];
        let tmpid = nodeid;
        while (node = id2node[tmpid]) {
            titles.unshift(node.title);
            tmpid = node.parentId;
        }
        let selected = false;
        if (bookmark_info) {
            selected = bookmark_info.parentId == nodeid;
        } else if (preferedFolder) {
            selected = titles.join(folder_path_separtor) == preferedFolder;
        } else if (previsousFolder) {
            selected = previsousFolder == nodeid;
        } else {
            selected = i == 0;
        }
        if (selected) {
            parentId = nodeid;
        }
        return titles;
    });
    if (!bookmark_info) { // 需要创建新书签
        let parentNode = id2node[parentId];
        let matchedMutexRules = mutexRules.filter(v => new RegExp(v).test(tab.url));
        let bookmark_index = null;
        // 检查互斥逻辑
        let mutexBookmarks = [];
        for (let id in id2node) {
            let node = id2node[id];
            if (node?.url) {
                if (matchedMutexRules.some(rule => {
                    const reg = new RegExp(rule);
                    let node_matches = reg.exec(node.url);
                    if (node_matches) {
                        let tab_matches = reg.exec(tab.url);
                        if (tab_matches && tab_matches.length == node_matches.length && tab_matches.every((v, i) => i == 0 || v == node_matches[i])) {
                            return true;
                        }
                    }
                })) { // 互斥书签
                    if (mutextSameIndex) {
                        bookmark_index = node.index;
                    }
                    parentNode.children = parentNode.children.filter(child => {
                        return child.id != node.id;
                    });
                    await chrome.bookmarks.remove(node.id);
                }
            }
        }
        if (bookmark_index == null) {
            bookmark_index = parentNode.children.length;
        } else {
            bookmark_index = Math.min(parentNode.children.length, bookmark_index);
        }
        bookmark_info = await chrome.bookmarks.create({
            parentId: parentId,
            index: bookmark_index,
            title: tab.title,
            url: tab.url,
        });
        if (result[StorageKey.AUTO_CLOSE_POPUP] == 1) {
            window.close();
        }
    } else { // 已有书签
        
    }
};
